######################################
## search.html
{% extends "base.html" %}

{% block headerbar %}
<h2>Search results</h2>
{% include "inc_form_search.html" %}
{% endblock %}

{% block body %}
    {% include "inc_bookmark.html" %}
{% endblock %}
#####################################
## inc_form_search.html
<form id="search" action="/search/" method="get">
<table>
<tr>
{% if user.is_anonymous %}
<td><input type="hidden" name="r" value="all" /></td>
<td><input type="text" name="q" size="50" value="" /></td>
<td><input type="submit" value="Search" /></td>
{% else %}
<td>Search</td>
<td>
<select name="r">
<option value="my">my bookmarks</option>
<option value="all">all bookmarks</option>
</select>
</td>
<td>for</td>
<td><input type="text" name="q" size="50" value="" /></td>
<td><input type="submit" value="Search" /></td>
{% endif %}
</tr>
</table>
</form>
#####################################
## inc_bookmark.html
<ol id="bookmarks">
{% for bm in bookmarks %}
<li class="xfolkentry" id="entry{{ bm.id }}">
<div class="link"><a href="{{ bm.get_absolute_url }}" rel="nofollow" class="taggedlink"
>{{ bm.note }}</a> - {{ bm.title|escape }} 
<a class="bylink" href="{{ bm.get_sap_url }}">(oss link)</a></div>
{% if bm.description %}<div class="description">{{ bm.description|escape }}</div>{% endif %}
<div class="meta">{{ bm.timedelta }} with tags {{ bm.tags_links }} by <a href="/bm/{{ bm.user.username }}"> {{ bm.user.username }} </a>
{% if bm.others %} and <a href="{{ bm.get_absolute_url }}">{{ bm.others }} other{{bm.others|pluralize}}</a> {% endif %}
{% if bm.own_bookmark %}
(<a href="/edit/{{ bm.id }}/">edit</a> - <a href="#" onclick="deleteBookmark(this, {{ bm.id }}); return false;">delete</a>) 
{% else %}
- <a href="{{ bm.url_copy }}">copy</a>
{% endif %}
</div>
</li>
{% endfor %}
</ol>

{% include "inc_pagination.html" %}
#####################################
## 
<p class="paging">
{% if has_previous %}<a href="{{ page_url }}?page=0">First</a>
{% else %}<span class="disable">First</span>{% endif %}
<span> / </span>
{% if has_previous %}<a href="{{ page_url }}?page={{ previous }}">Previous</a>
{% else %}<span class="disable">Previous</span>{% endif %}
<span> / </span>
{% if has_next %}<a href="{{ page_url }}?page={{ next }}">Next</a>
{% else %}<span class="disable">Next</span>{% endif %}
<span> / </span>
{% if has_next %}<a href="{{ page_url }}?page={{ lastpage }}">Last</a>
{% else %}<span class="disable">Last</span>{% endif %}
<span> / </span>Page {{ currentpage }} of {{ totalpages }}</p>
##############################################
##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

============================================================
##############################################################
## Computers
##############################################################
@login_required
def addComputer(request):
    if request.method == 'POST':
        comp_form = ContactForm(request.POST)
        if comp_form.is_valid():
            # Do form processing here...
            comp_form.save()
            # Always return an HttpResponseRedirect after successfully dealing
            # with POST data. This prevents data from being posted twice if a
            # user hits the Back button.
        return HttpResponseRedirect(reverse('wjContact.contacts.views.indexComputers'))
    else:
        comp_form = ContactForm()
    ## Need to change the name of the index.html template to "addForm" or similar.
    dummy = "dummy"
    return render_to_response('add.html', {'form': comp_form, 
                                           })

def detailsComputer(request, comp_id):
    """ Show the details for a specific computer"""
    details = get_object_or_404(Computers, pk=comp_id)
    details_dict = {'first_name': details.first_name, 
               'homephone': details.homephone,
               'database id' : details.id,
               'a string': 'a string',
    }
    return render_to_response('details.html', {'details': details_dict})

def indexComputer(request):
    """ List all computers."""
    computers = Computers.objects.values('first_name','last_name').order_by('last_name')
    return render_to_response('index.html', {'contact_list': names})
##############################################################
##############################################################
##############################################################

#class ContactForm(forms.Form):
    #first_name = forms.CharField(maxlength=20)
    #last_name = forms.CharField(maxlength=20)
    #address = forms.CharField(maxlength=200)
    #suburb = forms.CharField(maxlength=40)
    #country = forms.CharField(maxlength=40)
    #homephone = forms.CharField(maxlength=40)
    #workphone = forms.CharField(maxlength=40)
    #mobile = forms.CharField(maxlength=20)
    #email = forms.EmailField() # database field has maxlength = 60
    
#        return render_to_response('add.html', {'wendyform': wendyform, 
#                                           'mycwd': mycwd,
#                                           'settings_media_root': settings_media_root,
#                                           'settings_media_url': settings_media_url,
#                                           'css_files': css_files,
#                                           'settings': settings,
#                                           'username': request.user.username,
#                                           'is_authenticated' : request.user.is_authenticated(),
#                                           })
=====================================================================

<input type=checkbox name=contact_checkbox id=contact_checkbox onclick="contact_checkbox_onclick()">
<input type=checkbox name=recipient_checkbox id=recipient_checkbox onclick="recipient_checkbox_onclick()">



<label for="recipient" style="position: relative;left: 180px;bottom: -20px">Recipient </label>
<label for="contact" style="position: relative;left: -20px;bottom: -20px">Uncategorised Contact</label>

======================================================================

{% extends "global_nav.html" %}

{% block title %}wJ cOnTacT - adD RECIPIENT {% endblock %}


{% block content %}

<fieldset id=which_forms_row class=which_forms_row title="Contact Type" >

<div>
<input id = "contact" type="checkBox" onclick="if (this.checked) {contact_checkbox_onclick() }" > 


<br />
<input id = "recipient" type="checkBox" onclick="if (this.checked) {recipient_checkbox_onclick() }" > 

 <br />
 
 </div>
</fieldset>




<h1> <i> Tux says... </i> </h2>
<h3> Add a new recipient to the database by filling out the form below! </h3>
<form method="post" class = "contact_only_form" id = "contact_only_form">
    <table >{{ contact_only_form }}</table>
        <input type="hidden" name="which_form" value="this_is_the_contact_only_form" /> 
        <input type="submit" value = "Submit Contact"/>
</form>

<form method="post" class = "contact_and_recipient_form" id = "contact_and_recipient_form">
    <table >{{ contact_and_recipient_form }}</table>
        <input type="hidden" name="which_form" value="this_is_the_contact_and_recipient_form" /> 
        <input type="submit" value = "Submit Recipient"/>
</form>
{% endblock content %}

=============================================================================




<!--  <div class=various_contact_forms> -->

<div class=various_contact_forms_tabs>





<div id=contact_only_tab>
<a href="#contact_only_form">Contact Only</a>

<div> Some text on contact-only tab... </div>
<!--
<div id=contact_only_form>... Contact Only Form

<form method="post" class = "contact_only_form" id = "contact_only_form">
    <table >{{ contact_only_form }}</table>
        <input type="hidden" name="which_form" value="this_is_the_contact_only_form" /> 
        <input type="submit" value = "Submit Contact"/>
</form>
</div> <!-- end div "contact_only_form" --> -->
</div> <!-- end div "contact_only_tab" -->
 
 
<div id=contact_and_recipient_tab>
<a href="#contact_and_recipient">Contact and Recipient</a>
<div> Some text on contact-and-recipient form </div>
<!--
<div id=contact_and_recipient_form>... Contact and Recipient Form
<form method="post" class = "contact_and_recipient_form" id = "contact_and_recipient_form">
    <table >{{ contact_and_recipient_form }}</table>
        <input type="hidden" name="which_form" value="this_is_the_contact_and_recipient_form" /> 
        <input type="submit" value = "Submit Recipient"/>
</form>
</div> <!-- end div contact_and_recipient_form --> -->
</div> <!-- end div contact_and_recipient_tab -->







<div id=default_tab>
<a href="#default_tab">Clear</a>
<!-- by default, show no text --> 
</div> <!-- end div "default_tab" -->

</div> <!-- end div various_contact_forms_tabs -->
<!-- </div> <!-- end div various_contact_forms --> -->

==================================================================

   <div id=default_tab> <!-- start div id="default_tab" --> 
   <a href="#default_tab" onclick="contact_tablink_onclick('text_on_default_tab')">Default</a>
   <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
   <div id="text_on_default_tab"> This is the default tab. </div>
   </div> <!-- end div class="form_on_tab" --> 
   </div> <!-- end div id=default_tab --> 
   
   ==================================================================
   {% extends "global_nav.html" %}

{% block title %}wJ cOnTacT - adD RECIPIENT {% endblock %}


{% block content %}

<h1> <i> Tux says... </i> </h1>
<h3> 
Add a new recipient to the database by filling out the form below! 
</h3>






 <div class=contact_page_tabs>           <!-- start div class=contact_page_tabs -->
  
  <div id=tab1> <!-- start div id=tab1 --> 
   <a href="#tab1" onclick="contact_tablink_onclick('contact_only_form', 'contact_and_recipient_form')">Contact</a>
   <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
    <form method="post" class = "contact_only_form" id = "contact_only_form">
     <table>
      {{ contact_only_form }}
     </table>
      <input type="hidden" name="which_form" value="this_is_the_contact_only_form" /> 
      <input type="submit" value = "Submit Contact"/>
   </form>
  </div> <!-- end div class="form_on_tab" -->
  </div> <!-- end div id=tab1 --> 
   
  <div id=tab2>
   <a href="#tab2" onclick="contact_tablink_onclick('contact_and_recipient_form', 'contact_only_form')" >Recipient</a>
   <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
    <form method="post" class = "contact_and_recipient_form" id = "contact_and_recipient_form">
     <table>{{ contact_and_recipient_form }}</table>
       <input type="hidden" name="which_form" value="this_is_the_contact_and_recipient_form" />
       <input type="submit" value = "Submit Recipient"/>
    </form>
   </div> <!-- end div class="form_on_tab" --> 
   </div> <!-- end div id=tab2 --> 


 </div>                                 <!-- end div class=contact_page_tabs -->



{% endblock content %}
============================================================================

div.contact_page_tabs > div > div {
  background: purple;        /* purple */
  z-index: -2;            /* Behind, because the borders overlap */
  left: 0; top: 1.3em;        /* The top needs some calculation... */
  bottom: 0; right: 0;        /* Other sides flush with containing block */
/*  overflow: scroll;        /* Scroll bar if needed */
  padding: 0.3em;        /* Looks better */
  border: 0.1em outset #BBB}    /* 3D look */
  
  
  ===========================================================================
  ===========================================================================
===========================================================================
===========================================================================
  table.date {background-color: grey}
td.date {font-size: 12; color: skyblue}
table.menu {background-color: skyblue; width: 100%; height: 400}
td.menu {background-color: white; text-align: center; font-size: 12; width: 15%; height:20}
a:link {color: teal}
a:visited {color: black}
a:hover {color: #33CC66; font-style: italic}
a:active {color: #00FF00}
/* 2-Column example from Schmitt, chapter 4 */
Body {
  /* Make a margin and padding */
  margin: 80px 0 0 0;
  padding: 0 7% 0 260px;
  /* Put in a logo and back-ground color */
  background-image: url("../img/uk_penguin.jpg");
  background-repeat: no-repeat;
  color: black;
  background-color: #99CCFF;
  /* Some fonty stuff for the main body */
  font-family: Verdana, Helvetica, Arial, sans-serif;
  font-size: 1em;
  }
  
.leftcol {
  position: absolute;
  z-index: 5;
  width: 330px;
  top: 200px;
  left: 0;
  margin: 0;
  padding: 0 32px 0 32px3%;
  /* A different font for the left column */
  font-family: Verdana, Helvetica, Arial, sans-serif;
  font-size: 1.2em;
  }
  
.navitem {
  list-style: none;
  }


/* Tabbed example */
div.contact_page_tabs > div.form_on_tab {
 visibility: hidden}

div.contact_page_tabs {
  min-height: 10em;        /* No height: can grow if :target doesn't work */
  position: relative;        /* Establish a containing block */
  line-height: 1;        /* Easier to calculate with */
  z-index: 0}            /* So that we can put other things behind */
div.contact_page_tabs > div {
  display: inline}        /* We want the buttons all on one line */
div.contact_page_tabs > div > a {
  color: black;            /* Looks more like a button than a link */
  background: cornflowerblue;        /* Active tabs are cornflowerblue */
  padding: 0.2em;        /* Some breathing space */
  border: 0.1em outset #BBB;    /* Make it look like a button */
  border-bottom: 0.1em solid cornflowerblue} /* Visually connect tab and tab body */
  
div.contact_page_tabs > div:not(:target) > a {
  border-bottom: none;        /* Make the bottom border disappear */
  background: #8F88F2;        /* Inactive tabs are a slightly lighter blue */
  z-index: -3 !important;}
  
div.contact_page_tabs > div:target > a,    /* Apply to the targeted item or... */
:target #default_tab > a {        /* ... to the default item */
  border-bottom: 0.1em solid cornflowerblue; /* Visually connect tab and tab body */
  background: cornflowerblue}        /* Active tab is  cornflowerblue */
  
/* took stuff out here <wsl> */

 div.contact_page_tabs > div > div > form {
  background: cornflowerblue;        /* cornflowerblue */
  min-width: 500px;
  z-index: -1;            /* Behind, because the borders overlap */
  left: 0; top: 5.3em;        /* The top needs some calculation... */
  bottom: 0; right: 0;        /* Other sides flush with containing block */
/*  overflow: scroll;        /* Scroll bar if needed */
  padding: 5.3em;        /* Looks better */
  border: 0.1em outset #BBB}    /* 3D look */
  
div.contact_page_tabs > div:not(:target) > div { /* Protect CSS1 & CSS2 browsers */
  position: absolute }        /* All these DIVs overlap */
  
div.contact_page_tabs > div:target > div, :target #default_tab > div {
  position: absolute;        /* All these DIVs overlap */
  z-index: -1}            /* Raise it above the others */



/*
.contactform {
  color: black;
  background-color: #99CCFF; 
  width: 10%;
  float: center;
  padding: 10%;
  margin: 15px;
  }
*/

.devstuff {
  padding: 10px;
  }
  
div.devstuff {
  float: right;
  width: 100%; 
  margin: 40px 0 0 0;
  border: 20px solid #000;
  background-color: orange;
  }
  
p.devstuff {
    font-size: 0.7em;
  }
   
  
h1.devstuff {
  float: right;
  }
  
.messagelist { font-size: 25px; color: red; list-style: none; }

#logged_in_message { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:13px; text-align:right; 
 color: #6633cc; }
 
#not_logged_in_message { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:13px; text-align:right; 
 color: #993333 }
  
  
===========================================================================
===========================================================================
===========================================================================
===========================================================================



 <div class=contact_page_tabs>           <!-- start div class=contact_page_tabs -->
  
  <div id=tab1> <!-- start div id=tab1 --> 
   <a href="#tab1" onclick="contact_tablink_onclick('contact_only_form', 'contact_and_recipient_form')">Contact</a>
   <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
    <form method="post" class = "contact_only_form" id = "contact_only_form">
     <table>
      {{ contact_only_form }}
     </table>
      <input type="hidden" name="which_form" value="this_is_the_contact_only_form" /> 
      <input type="submit" value = "Submit Contact"/>
   </form>
  </div> <!-- end div class="form_on_tab" -->
  </div> <!-- end div id=tab1 --> 
   
  <div id=tab2>
   <a href="#tab2" onclick="contact_tablink_onclick('contact_and_recipient_form', 'contact_only_form')" >Recipient</a>
   <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
    <form method="post" class = "contact_and_recipient_form" id = "contact_and_recipient_form">
     <table>{{ contact_and_recipient_form }}</table>
       <input type="hidden" name="which_form" value="this_is_the_contact_and_recipient_form" />
       <input type="submit" value = "Submit Recipient"/>
    </form>
   </div> <!-- end div class="form_on_tab" --> 
   </div> <!-- end div id=tab2 --> 


 </div>                                 <!-- end div class=contact_page_tabs -->



{% endblock content %}




===========================================================================
===========================================================================
===========================================================================
===========================================================================
<script language="javascript">


function contact_tablink_onclick(clicked_link_id, other_link_id)
{
  document.getElementById(clicked_link_id).style.visibility="visible";
  document.getElementById(other_link_id).style.visibility="hidden";
}

</script>



===========================================================================
===========================================================================
===========================================================================
===========================================================================


<div id="ddcolortabs">
<ul>

<li style="margin-left: 1px">
 <a href="#tab1" title = "Contact" onclick="contact_tablink_onclick('contact_only_form', 'contact_and_recipient_form')">
  <span>
   Contact
  </span>
 </a>
    <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
    <form method="post" class = "contact_only_form" id = "contact_only_form">
     <table>
      {{ contact_only_form }}
     </table>
      <input type="hidden" name="which_form" value="this_is_the_contact_only_form" /> 
      <input type="submit" value = "Submit Contact"/>
   </form>
  </div> <!-- end div class="form_on_tab" -->
</li>




<li>
 <a href="#tab2" title="Recipient" onclick="contact_tablink_onclick('contact_and_recipient_form', 'contact_only_form')" >
  <span>
   Recipient
  </span>
 </a>
    <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
    <form method="post" class = "contact_and_recipient_form" id = "contact_and_recipient_form">
     <table>{{ contact_and_recipient_form }}</table>
       <input type="hidden" name="which_form" value="this_is_the_contact_and_recipient_form" />
       <input type="submit" value = "Submit Recipient"/>
    </form>
   </div> <!-- end div class="form_on_tab" --> 
</li>

</ul>
</div>

================================================================================
     <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
    <form method="post" class = "contact_and_recipient_form" id = "contact_and_recipient_form">
     <table>{{ contact_and_recipient_form }}</table>
       <input type="hidden" name="which_form" value="this_is_the_contact_and_recipient_form" />
       <input type="submit" value = "Submit Recipient"/>
    </form>
   </div> <!-- end div class="form_on_tab" --> 
   
   
   
       <div class="form_on_tab"> <!-- start div class="form_on_tab" --> 
    <form method="post" class = "contact_only_form" id = "contact_only_form">
     <table>
      {{ contact_only_form }}
     </table>
      <input type="hidden" name="which_form" value="this_is_the_contact_only_form" /> 
      <input type="submit" value = "Submit Contact"/>
   </form>
  </div> <!-- end div class="form_on_tab" -->
================================================================================

from django import newforms as forms
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import redirect_to_login
from django.core.paginator import ObjectPaginator

from wjContact.contacts.constants import MSG_CODES, DEFAULT_LISTSIZE
from wjContact.contacts.models import Contact, Recipient, Group, Volunteer

## Nicked from 
## http://hotoss.googlecode.com/svn/trunk/bookmark/constants.py
def paginator_dic(paginator, page, page_url):
    d = {}
    d['is_paginated'] = paginator.pages > 1
    d['has_next'] = paginator.has_next_page(page)
    d['has_previous'] = paginator.has_previous_page(page)
    d['next'] = page + 1
    d['previous'] = page - 1
    d['currentpage'] = page+1
    d['totalpages'] = paginator.pages
    d['lastpage'] = paginator.pages - 1
    d['page_url'] = page_url
    return d

## Nicked from 
## http://hotoss.googlecode.com/svn/trunk/bookmark/constants.py
def get_listsize(user):
    if user.is_anonymous():
        listsize = DEFAULT_LISTSIZE
    else:
        # to be implemented 'later' :)
        #listsize = user.get_profile().listsize
        listsize = DEFAULT_LISTSIZE
    return listsize
    
def logout(request, next_page=None, template_name='accounts/logged_out.html'):
    from django.contrib.auth.views import logout
    return logout(request, next_page=None, template_name=template_name)  
    
def viewProfile(request):
    return render_to_response('accounts/profile.html', 
        context_instance=RequestContext(request))
        
def underConstruction(request):
    """ This view just throws out the 'under construction' page. """
    return render_to_response('under_construction.html', 
                              context_instance=RequestContext(request))

def editContact(request):
    ## do stuff
    #edit_form
    ## See contrib/admin/views.main.render_change_form for some ideas...
    """# Create an Author.
>>> a = Author(name='Joe Smith', title='MR', birth_date=None)
>>> a.save()

# Create a form for this particular Author.
>>> AuthorForm = form_for_instance(a)

# Instantiate the form.
>>> f = AuthorForm() """
    if request.method == 'POST':
        edit_form = ContactForm(request.POST)  
        edit_form.fields['state'].max_length = 2
        if edit_form.is_valid():
            # Do form processing here...    
            #edit_from.auto_id =
            #new = edit_form._model.objects.get(pk=2)                   
            new.save()
   
            # Always return an HttpResponseRedirect after successfully dealing
            # with POST data. This prevents data from being posted twice if a
            # user hits the Back button.
            return HttpResponseRedirect(reverse('wjContact.contacts.views.indexContacts'))
        else:
            return render_to_response('edit.html', 
                                      {'edit_form': edit_form}, 
                                      context_instance=RequestContext(request))     
    else:  
        ## Display the details for the contact we are editing.
        contact = Contact.objects.get(pk=2)
        EditContactForm = forms.form_for_instance(contact)
        edit_form = EditContactForm()
        return render_to_response('edit.html', 
            {'edit_form': edit_form},
            context_instance=RequestContext(request))
editContact = login_required(editContact)

def addContact(request):
    """ """
    ## See contrib/admin/views.main.add_stage() for some ideas...
    ContactForm = forms.form_for_model(Contact)
    ## If user has hit the submit button, the request method will be 'POST'...
    if request.method == 'POST':  
        filled_form = ContactForm(request.POST)
        filled_form.fields['state'].max_length = 2
        ## and the data in the form is all valid...
        if filled_form.is_valid():
            ## Here we will check for rough matches existing in database 
            ## already.
            cleaned_form = filled_form.clean()
            fname = cleaned_form['first_name']
            dupes = Contact.objects.filter(first_name__icontains=fname)
            ## Check that this entry does not duplicate an existing one...
            if dupes:
                ## List possible duplicates
                return render_to_response('dupes.html', {'dupelist': dupes}) 
            ## And if there are no duplicates, save the data from this form 
            ## to the database, and redirect to the list of all existing 
            ## contacts. Always return an HttpResponseRedirect after 
            ## successfully dealing with POST data. This prevents data from 
            ## being posted twice if a user hits the Back button.                              
            else:
                filled_form.save()
                msg = "New contact %s %s successfully added." % (fname, cleaned_form['last_name'])
                request.user.message_set.create(message=msg)
                return HttpResponseRedirect(reverse
                    ('wjContact.contacts.views.addContact'))                                
        else:
            return render_to_response('add.html', {'form': filled_form })
    ## If request.method is not 'POST', then the user has not yet hit the 
    ## submit button  -->  render an empty form for them to fill in ...       
    else:
        empty_form = ContactForm()
        return render_to_response('add.html', {'form' : empty_form},
            context_instance=RequestContext(request))                                            
addContact = login_required(addContact)

## Here we make classes to represent the various kinds of forms we are
## going to use.
def new_save(self):
    """ Over-ride our save method to enable saving default values."""
    cleaned_form = self.clean_data
    import datetime
    new_contact = Contact(first_name=cleaned_form['first_name'],
        last_name = cleaned_form['last_name'],
        address = "99 Long street",
        suburb = "Sunny Hills", state = "Ca",
        country = "America",
        email = "%s%s@%s.com" % (cleaned_form['first_name'], 
            cleaned_form['last_name'], 
            cleaned_form['last_name']),
        date_added = datetime.datetime.now(),
            )
    new_contact.save()
    
ContactForm = forms.form_for_model(Contact)
## attach our re-defined save() method.
## Can possibly just set the requiredness attr on the field rather than
## attaching a whole new field, but this works for now...
ContactForm.base_fields['date_added'] = forms.DateTimeField(required=False)
ContactForm.save = new_save

class RecipientForm(forms.Form):
    """
    A form for displaying both contact fields and recipient fields with a 
    single 'submit' button.
    """
    ## The next few fields are for general contact details - details which are
    ## stored in the Contact table.
    first_name = forms.CharField(max_length=20)
    first_name.model = "Contact"
    last_name = forms.CharField(max_length=20)
    last_name.model = "Contact"
    address = forms.CharField(max_length=200)
    suburb = forms.CharField(max_length=40)
    state = forms.CharField(max_length=2)
    country = forms.CharField(max_length=40)
    email = forms.EmailField()
      
    ## The next fields are for details that relate specifically to 
    ## recipient-type contacts details which are
    ## stored in the Recipient table.
    ## Grab in the list of concession types used as choices for this field
    ## by the Recipient model.
    CONCESSION_CHOICES = Recipient.CONCESSION_TYPES
    INTERNET_TYPES = Recipient.INTERNET_TYPES
    
    concession_type = forms.ChoiceField(choices=CONCESSION_CHOICES)
    concession_type.model = "Recipient"
    concession_checked_by = forms.ModelChoiceField(Volunteer.objects.all())
    referring_org = forms.ModelChoiceField(Group.objects.all())
    install_windows = forms.NullBooleanField()
    install_windows.model = "Recipient"
    stay_with_linux = forms.NullBooleanField()
    stay_with_linux.model = "Recipient"
     
    have_not_used_a_computer = forms.BooleanField()
    can_type_documents = forms.BooleanField()
    can_use_keyboard_and_mouse = forms.BooleanField()
    can_use_email = forms.BooleanField()
    can_use_internet = forms.BooleanField()
    has_attended_training = forms.BooleanField()
    internet_type = forms.ChoiceField(choices=INTERNET_TYPES)
    
    def save(self):
        """
        Over-ride our save method so that we can save fields to more than
        one table.
        """
        
        ## We need to save stuff into two different database tables
        ## here. First we save the contact details into the Contact
        ## table.
        cleaned_form = self.clean_data
        import datetime
        new_contact = Contact(first_name=cleaned_form['first_name'],
            last_name = cleaned_form['last_name'],
            address = "99 Long street",
            suburb = "Windy Hills", state = "Ca",
            country = "America",
            email = "%s%s@%s.com" % (cleaned_form['first_name'], 
                cleaned_form['last_name'], 
                cleaned_form['last_name']),
            date_added = datetime.datetime.now(),
                )
        new_contact.save()
        # Now save the recipient details into the recipient table,
        # and set the 'contact' to be the contact we just created.
        kylie = Volunteer.objects.get(pk=1)
        registrar = Group.objects.get(pk=1)
        new_recipient = Recipient(contact=new_contact,
        concession_type = "other",
        concession_checked_by = kylie,
        referring_org = registrar,
        install_windows = False,
        stay_with_linux = True,
        have_not_used_a_computer = False,
        can_type_documents = True,
        can_use_keyboard_and_mouse = True,
        can_use_email = True,
        can_use_internet = True,
        has_attended_training = True,
        internet_type = "dialup")
        new_recipient.save()
        
    
def handle_contact_form(request, filled_contact_form): 
    
    if filled_contact_form.is_valid():
        ## Here we will check for rough matches existing in database 
        ## already.
        cleaned_form = filled_contact_form.clean()  
        fname = cleaned_form['first_name']
        dupes = Contact.objects.filter(first_name__icontains=fname)
        ## Check that this entry does not duplicate an existing one...
        if dupes:
            ## List possible duplicates
            return render_to_response('dupes.html', {'dupelist': dupes}) 
        ## And if there are no duplicates, save the data from this form 
        ## to the database, and redirect to the list of all existing 
        ## contacts. Always return an HttpResponseRedirect after 
        ## successfully dealing with POST data. This prevents data from 
        ## being posted twice if a user hits the Back button.                              
        else:
            filled_contact_form.save()
            msg = "New contact %s %s successfully added." % (cleaned_form['first_name'], cleaned_form['last_name'])
            request.user.message_set.create(message=msg)
            return HttpResponseRedirect(reverse
                ('wjContact.contacts.views.addRecipient')) 
    ## If it's not valid, render failure message
    else: 
        msg = "Argle Blargle. Couldn't add new contact %s %s." % (filled_contact_form['first_name'].data, filled_contact_form['last_name'].data)
        request.user.message_set.create(message=msg)
#        return render_to_response('add_recipient.html', 
#                {'contact_only_form': filled_contact_form, 
#                 #'contact_and_recipient_form' : filled_recipient_form 
#                }
#            )
        return HttpResponseRedirect(reverse
            ('wjContact.contacts.views.addRecipient')) 
 
def handle_recipient_form(request, filled_recipient_form): 
    if filled_recipient_form.is_valid():
        ## Here we will check for rough matches existing in database 
        ## already.
        cleaned_form = filled_recipient_form.clean()
        fname = cleaned_form['first_name']
        dupes = Contact.objects.filter(first_name__icontains=fname)
        ## Check that this entry does not duplicate an existing one...
        if dupes:
            ## List possible duplicates
            return render_to_response('dupes.html', {'dupelist': dupes}) 
        ## And if there are no duplicates, save the data from this form 
        ## to the database, and redirect to the list of all existing 
        ## contacts. Always return an HttpResponseRedirect after 
        ## successfully dealing with POST data. This prevents data from 
        ## being posted twice if a user hits the Back button.                              
        else:
            filled_recipient_form.save()
            msg = "New recipient %s %s successfully added with additional details relevant for recipients." % (cleaned_form['first_name'], cleaned_form['last_name'])
            request.user.message_set.create(message=msg)
            return HttpResponseRedirect(reverse
                ('wjContact.contacts.views.addRecipient')) 
    ## If it's not valid, render failure message
    else: 
        msg = "Iggle Bliggle. Couldn't add new recipient %s %s." % (filled_recipient_form['first_name'].data, filled_recipient_form['last_name'].data)
        request.user.message_set.create(message=msg)
        return HttpResponseRedirect(reverse
            ('wjContact.contacts.views.addRecipient'))                                
    
def addRecipient(request):
    """ """
    ## See contrib/admin/views.main.add_stage() for some ideas...   
    ## If user has hit the submit button, the request method will be 'POST'...
    if request.method == 'POST':  
        filled_contact_form = ContactForm(request.POST)
        filled_recipient_form = RecipientForm(request.POST)
        ## and the data in the form is all valid...
        if request.POST['which_form'] == 'this_is_the_contact_only_form':
            return handle_contact_form(request, filled_contact_form)                    
        if request.POST['which_form'] == 'this_is_the_contact_and_recipient_form':
            return handle_recipient_form(request, filled_recipient_form)
        else:
            exception_msg = "Looks like for some reason the request.POST " + \
                "variable carries no information about which form button " + \
                "was clicked...If you have added a new section to the " + \
                "template recently, please check that the template is "  + \
                "correctly setting this information using a hidden input." 
            raise Exception, exception_msg
    ## If request.method is not 'POST', then the user has not yet hit the 
    ## submit button  -->  render an empty form for them to fill in ...       
    else:
        empty_contact_form = ContactForm()
        empty_recipient_form = RecipientForm()
        return render_to_response('add_recipient.html', 
            {
             'contact_only_form' : empty_contact_form, 
             'contact_and_recipient_form' : empty_recipient_form
             },
            context_instance=RequestContext(request)
            )                                            
addRecipient = login_required(addRecipient)

def detailsContact(request, contact_id):
    """ Show the details for a specific contact"""
    details = get_object_or_404(Contact, pk=contact_id)
    details_dict = {'first_name': details.first_name, 
               'homephone': details.homephone,
               'database id' : details.id,
               'a string': 'a string',
    }
    return render_to_response('details.html', 
        {'details': details_dict},
        context_instance=RequestContext(request))

def indexContact(request):
    """ List all contacts."""
    names = Contact.objects.values('first_name','last_name').order_by('last_name')
    return render_to_response('index.html', 
        {'contact_list': names},
        context_instance=RequestContext(request))

## The following code is based on code from the open-source 
## 'Hotoss' project. <licensing> 
## From http://hotoss.googlecode.com/svn/trunk/bookmark/views.py
def search(request):
#    if not query:
#            return HttpResponseRedirect('/')
    if not request.GET.items():
        #return HttpResponseRedirect('/contacts/add/')
        ## 1. display a search form - built from the Contact model. This is just
        ## an "unbound" ContactForm.
        ContactForm = forms.form_for_model(Contact)
        search_form = ContactForm()
        return render_to_response('search.html', 
            {'search_form' : search_form},
            context_instance=RequestContext(request))  
    ## 1. display a search form - built from the Contact model. This is just
    ## an "unbound" ContactForm.
    ContactForm = forms.form_for_model(Contact)
    search_form = ContactForm(request.GET)
    ## For searching, not all fields are required.  
    for field in search_form.fields.values():  
        field.required = False 
    ## No point searching on invalid entries, so check validity first.        
    if search_form.is_valid():
        fname = search_form.clean()['first_name']
        results = Contact.objects.filter(first_name__icontains=fname)
        ## List results.
        paginator = ObjectPaginator(results , get_listsize(request.user))
        page = int(request.GET.get('page', 0))
        msg = int(request.GET.get('msg', 0))
        if paginator.pages:
            single_page_of_results = paginator.get_page(page)
        else:
            results = []
        abs_url = '/contacts/search/'
        d = {'msg': MSG_CODES.get(msg,''), 
             'search_results': single_page_of_results, 
             'abs_url': abs_url }
    ## We will also be rendering a new, empty search form for them to 
    ## search again. Get this ready now.
    new_empty_search_form = ContactForm()
    d.update(paginator_dic(paginator, page, abs_url))
    d.update({'search_form': new_empty_search_form })
    context = RequestContext(request, d)
    return render_to_response('search.html', context)  
searchContactForm = login_required(search)        


================================================================================

def oldAddRecipient(request):
    """ """
    ## See contrib/admin/views.main.add_stage() for some ideas...   
    ## If user has hit the submit button, the request method will be 'POST'...
    if request.method == 'POST':  
        filled_contact_form = ContactForm(request.POST)
        filled_recipient_form = RecipientForm(request.POST)
        ## and the data in the form is all valid...
        if request.POST['which_form'] == 'this_is_the_contact_only_form':
            return handle_contact_form(request, filled_contact_form)                    
        if request.POST['which_form'] == 'this_is_the_contact_and_recipient_form':
            return handle_recipient_form(request, filled_recipient_form)
        else:
            exception_msg = "Looks like for some reason the request.POST " + \
                "variable carries no information about which form button " + \
                "was clicked...If you have added a new section to the " + \
                "template recently, please check that the template is "  + \
                "correctly setting this information using a hidden input." 
            raise Exception, exception_msg
    ## If request.method is not 'POST', then the user has not yet hit the 
    ## submit button  -->  render an empty form for them to fill in ...       
    else:
        empty_contact_form = ContactForm()
        empty_recipient_form = RecipientForm()
        return render_to_response('add_recipient.html', 
            {
             'contact_only_form' : empty_contact_form, 
             'contact_and_recipient_form' : empty_recipient_form
             },
            context_instance=RequestContext(request)
            )                                            
oldAddRecipient = login_required(oldAddRecipient)

================================================================================
def addContact(request):
    """ """
    ## See contrib/admin/views.main.add_stage() for some ideas...
    ContactForm = forms.form_for_model(Contact)
    ## If user has hit the submit button, the request method will be 'POST'...
    if request.method == 'POST':  
        filled_form = ContactForm(request.POST)
        filled_form.fields['state'].max_length = 2
        ## and the data in the form is all valid...
        if filled_form.is_valid():
            ## Here we will check for rough matches existing in database 
            ## already.
            cleaned_form = filled_form.clean()
            fname = cleaned_form['first_name']
            dupes = Contact.objects.filter(first_name__icontains=fname)
            ## Check that this entry does not duplicate an existing one...
            if dupes:
                ## List possible duplicates
                return render_to_response('dupes.html', {'dupelist': dupes}) 
            ## And if there are no duplicates, save the data from this form 
            ## to the database, and redirect to the list of all existing 
            ## contacts. Always return an HttpResponseRedirect after 
            ## successfully dealing with POST data. This prevents data from 
            ## being posted twice if a user hits the Back button.                              
            else:
                filled_form.save()
                msg = "New contact %s %s successfully added." % (fname, cleaned_form['last_name'])
                request.user.message_set.create(message=msg)
                return HttpResponseRedirect(reverse
                    ('wjContact.contacts.views.addContact'))                                
        else:
            return render_to_response('add.html', {'a_form': filled_form })
    ## If request.method is not 'POST', then the user has not yet hit the 
    ## submit button  -->  render an empty form for them to fill in ...       
    else:
        empty_form = ContactForm()
        return render_to_response('add_all_contact_types.html', {'a_form' : empty_form},
            context_instance=RequestContext(request))                                            
addContact = login_required(addContact)
================================================================================
class RecipientForm(forms.Form):
    """
    A form for displaying both contact fields and recipient fields with a 
    single 'submit' button.
    """
    ## The next few fields are for general contact details - details which are
    ## stored in the Contact table.
    first_name = forms.CharField(max_length=20, initial="New")
    last_name = forms.CharField(max_length=20, initial="Recipient")
    address = forms.CharField(max_length=200, initial="5 Nice Street")
    suburb = forms.CharField(max_length=40, initial="North Melbourne")
    state = forms.CharField(max_length=2, initial="Vi")
    country = forms.CharField(max_length=40, initial='Australia')
    email = forms.EmailField(initial="recipient@place.org")
      
    ## The next fields are for details that relate specifically to 
    ## recipient-type contacts details which are
    ## stored in the Recipient table.
    ## Grab in the list of concession types used as choices for this field
    ## by the Recipient model.
    CONCESSION_CHOICES = Recipient.CONCESSION_TYPES
    INTERNET_TYPES = Recipient.INTERNET_TYPES
    
    concession_type = forms.ChoiceField(choices=CONCESSION_CHOICES, initial="other")
    concession_checked_by = forms.ModelChoiceField(Volunteer.objects.all())
    referring_org = forms.ModelChoiceField(Group.objects.all())
    install_windows = forms.BooleanField(initial=False)
    stay_with_linux = forms.BooleanField(initial=True)  
    have_not_used_a_computer = forms.BooleanField(initial=False)
    can_type_documents = forms.BooleanField(initial=True)
    can_use_keyboard_and_mouse = forms.BooleanField(initial=True)
    can_use_email = forms.BooleanField(initial=True)
    can_use_internet = forms.BooleanField(initial=True)
    has_attended_training = forms.BooleanField(initial=False)
    internet_type = forms.ChoiceField(choices=INTERNET_TYPES, initial="none")
    
    def save(self):
        """
        Over-ride our save method so that we can save fields to more than
        one table.
        """
        
        ## We need to save stuff into two different database tables
        ## here. First we save the contact details into the Contact
        ## table.
        cleaned_form = self.clean_data
        new_contact = Contact(first_name=cleaned_form['first_name'],
            last_name = cleaned_form['last_name'],
            address = "99 Long street",
            suburb = "Windy Hills", state = "Ca",
            country = "America",
            email = "%s%s@%s.com" % (cleaned_form['first_name'], 
                cleaned_form['last_name'], 
                cleaned_form['last_name']),
            date_added = datetime.date.today(),
                )
        new_contact.save()
        # Now save the recipient details into the recipient table,
        # and set the 'contact' to be the contact we just created.
        kylie = Volunteer.objects.get(pk=1)
        registrar = Group.objects.get(pk=1)
        new_recipient = Recipient(contact=new_contact,
            concession_type = "other",
            concession_checked_by = kylie,
            referring_org = registrar,
            install_windows = False,
            stay_with_linux = True,
            have_not_used_a_computer = False,
            can_type_documents = True,
            can_use_keyboard_and_mouse = True,
            can_use_email = True,
            can_use_internet = True,
            has_attended_training = True,
            internet_type = "dialup")
        new_recipient.save()

================================================================================
I am working on getting the kond of listig ficntionality that is in the Admin interface for our project. Ie things like the fileters and the search-bar, as this would save us a lot of work! To this end, I've copied over a whole file from the Admin django code called 'main.py', which containsthe views for listing and for changing various database entities. We are onlyintreested in the listing ones at the oment,as the changing ones use the oldfoms package which we are avoiding.

Anyway, to be able to use our existing views *and* the ones found in main.py, I have made a directory called views and turned it into a package by providing an __init__ file
================================================================================
       <fieldset title="Phones" style="padding: 20px;  margin:10px;">
       <legend style="font-weight: bold">Phones</legend>
       
       {% for phone_input in form.phone_inputs %}
       <fieldset title="Phone" style="padding: 20px; border: dashed; margin:10px;">
       <legend style="font-weight: bold">Phone</legend>
       <p>
       <span>{{ form.phone_number.label_tag }} {{ form.phone_number }}</span>
       <span class="helptext">{{ form.phone_number.help_text }}</span>
       {% if form.phone_number.errors %}<ul class="errorlist">{{ form.phone_number.errors }}</ul>{% endif %}
       <span>{{ form.phone_type.label_tag }} {{ form.phone_type }}</span>
       <span class="helptext">{{ form.phone_type.help_text }}</span>
       {% if form.phone_type.errors %}<ul class="errorlist">{{ form.phone_type.errors }}</ul>{% endif %}
       <span>{{ form.preferred.label_tag }} {{ form.preferred }}</span>
       <span class="helptext">{{ form.preferred.help_text }}</span>
       {% if form.preferred.errors %}<ul class="errorlist">{{ form.preferred.errors }}</ul>{% endif %}
       </p>
       </fieldset>
       {% endfor %}
       <input type="checkbox" value = "add_another_phone"> Add another phone number? </input>
       </fieldset>
================================================================================
       <span>{{ phone_input.phone_type.label_tag }} {{ phone_input.phone_type }}</span>
       <span class="helptext">{{phone_input.phone_type.help_text }}</span>
       {% if phone_input.phone_type.errors %}<ul class="errorlist">{{ phone_input.phone_type.errors }}</ul>{% endif %}
       <span>{{ phone_input.preferred.label_tag }} {{ phone_input.preferred }}</span>
       <span class="helptext">{{ phone_input.preferred.help_text }}</span>
       {% if phone_input.preferred.errors %}<ul class="errorlist">{{phone_input.preferred.errors }}</ul>{% endif %}
================================================================================


       {% for item in form.phone_inputs %}
       <fieldset title="Phone" style="padding: 20px; border: dashed; margin:10px;">
       <legend style="font-weight: bold">Phone</legend>
       <p>
       <span>{{ item.0.label_tag }} {{ item.0 }}</span>
       <span class="helptext">{{ item.0.help_text }}</span>
       {% if item.0.errors %}<ul class="errorlist">{{ item.0.errors }}</ul>{% endif %}       
       
  <span>{{ item.1.label_tag }} {{ item.1 }}</span>
       <span class="helptext">{{ item.1.help_text }}</span>
       {% if item.1.errors %}<ul class="errorlist">{{ item.1.errors }}</ul>{% endif %}       
       
       
        <span>{{ item.2.label_tag }} {{ item.2 }}</span>
       <span class="helptext">{{ item.2.help_text }}</span>
       {% if item.2.errors %}<ul class="errorlist">{{ item.2.errors }}</ul>{% endif %}             
        
       </p>
       </fieldset>
       {% endfor %}
================================================================================
       <fieldset title="Multiphone" style="padding: 20px;  margin:10px;">
       <legend style="font-weight: bold">Email</legend>
       <p>
       <span>{{ form.phones_field_set.label_tag }} {{ form.phones_field_set }}</span>
       <span class="helptext">{{ form.phones_field_set.help_text }}</span>
       {% if form.phones_field_set.errors %}<ul class="errorlist">{{ form.phones_field_set.errors }}</ul>{% endif %}
       </p>
      </fieldset>
      
      

       <fieldset title="Phones" style="padding: 20px;  margin:10px;">
       <legend style="font-weight: bold">Phones</legend>
       
       
       
       {% for item in form.phone_inputs %}
       <fieldset title="Phone" style="padding: 20px; border: dashed; margin:10px;">
       <legend style="font-weight: bold">Phone</legend>
       <p>
       <span>{{ item.phone_number.label_tag }} {{ item.phone_number }}</span>
       <span class="helptext">{{ item.0.help_text }}</span>
       {% if item.phone_number.errors %}<ul class="errorlist">{{ item.phone_number.errors }}</ul>{% endif %}       
       
  <span>{{ item.phone_type.label_tag }} {{ item.phone_type }}</span>
       <span class="helptext">{{ item.phone_type.help_text }}</span>
       {% if item.phone_type.errors %}<ul class="errorlist">{{ item.phone_type.errors }}</ul>{% endif %}       
       
       
        <span>{{ item.preferred.label_tag }} {{ item.preferred }}</span>
       <span class="helptext">{{ item.preferred.help_text }}</span>
       {% if item.preferred.errors %}<ul class="errorlist">{{ item.preferred.errors }}</ul>{% endif %}             
        
       </p>
       </fieldset>
       {% endfor %}
       
       
       <input type="checkbox" value = "add_another_phone"> Add another phone number? </input>
       </fieldset>

       
       <fieldset title="Date Added" style="padding: 20px;  margin:10px;">
       <legend style="font-weight: bold">Date Added</legend>
       <p>
       <span>{{ form.date_added.label_tag }} {{ form.date_added }}</span>
       <span class="helptext">{{ form.date_added.help_text }}</span>
       {% if form.date_added.errors %}<ul class="errorlist">{{ form.date_added.errors }}</ul>{% endif %}
       </p>
       </fieldset>
      

      <input type="submit" value = "Submit Contact"/>
    </form>
  </div>                                    <!-- end div class="form_on_tab" -->
   
 

</div>                                          <!-- end div id="hold_forms" -->
{% endblock forms %}

================================================================================
    def add_language_fields(self, touched_add_form, touched_edit_form,
        fresh_add_form, fresh_edit_form):
        """
        Add one or more language fields. 
        """
        ## For 'touched' forms, we now don't need to do much more - the language
        ## etc fields will be in the request, and so the fields will have been
        ## correctly built onto the form by the superclass __init__ methods that
        ## was called earlier. We just need to build a self.language_field_list
        ## so that the template can display us properly and so on.
        ## This will store a list of the names of all the language fields on 
        ## this form, ie language_1, language_2, and so on.
        self.language_field_list = []
        
#        if touched_add_form or touched_edit_form:
#            for key in self.data:
#                if key[0:9] == 'language_':
#                    self.language_field_list.append(key)
#                    
        if touched_edit_form:
            for key in self.data:
                if key[0:9] == 'language_':
                    self.language_field_list.append(key)
                    ## Hopefully it doesn't matter what the initial value is,
                    ## since as soon as any one tryies to 'get' the item, it
                    ## will go through __getitem__ which will create a bound
                    ## field, which will get it's data out of self.data.                
                    self.fields[key] = LanguageFields(widget=
                        LanguageFieldsWidget()) 
                
        ## For 'fresh' forms, we still need to add 
        ## these fields, as they were not part of the base_fields in the class
        ## definition.
        ## 

        if fresh_add_form:
            ## If there is no contact_id, we are a fresh add form - we just
            ## offer them a default number of language fields, say 2 or 3.
            num_languages=2           
            for i in range(num_languages):
                field_name = 'language_%s' % (i+1)     
                self.fields[field_name] = LanguageFields(widget=
                        LanguageFieldsWidget()) 
                self.language_field_list.append(field_name)
        if fresh_edit_form:
            ## If we have a contact_id already, then we are an edit form, and 
            ## we need to pull out any existing language data from the database.        
            user_language_joins = UserLanguage.objects.filter(
                contact__exact=self.contact_id)
            #pdb.set_trace()
            for i, entry in enumerate(user_language_joins):
                language_name = Language.objects.get(id=entry.language_name_id).language_name
                field_name = 'language_%s' % (i+1)    
                self.fields[field_name] = LanguageFields(widget=
                        LanguageFieldsWidget()) 
                self.language_field_list.append(field_name) 
                ## Need to put the value into the form data as well, we can't
                ## expect the form to get the data out of the field...
                ## Why oh Why?!
                self.data[field_name]=language_name
    
    def save_language_fields(self):
        """single_language = \
            [self.clean_data['single_language'], self.fields['single_language']]
        self.save_single_language(single_language)"""
        ##
        ##
        self.language_field_list = []
        
        for key in self.data:
            value_field_pair = []
            if key[0:9] == 'language_':
                self.language_field_list.append(key)
                pdb.set_trace()
                value_field_pair.append(self.clean_data[key])
                ## Hopefully it doesn't matter what the initial value is,
                ## since as soon as any one tries to 'get' the item, it
                ## will go through __getitem__ which will create a bound
                ## field, which will get it's data out of self.data.
                ## Seems bizzarro, but considering that self.data and 
                ## self.fields are actually seperate until the field becomes
                ##"bound" during the __getitem__ call, it should work out ok...
                value_field_pair.append(forms.CharField(max_length=40, 
                    initial='Abbotsford', required=False))
        pdb.set_trace()
                
        
                
    def save_single_language(self, single_language):
            ## our 'cleaned' language-field contains a compressed version of the
            ## data, ie something like u'Spanish#spoken#primary'
            ## Luckily our language-widget knows how to decompress this!
            cleaned_and_compressed = single_language[0]
            actual_single_language_field = single_language[1]
            decompressed = actual_single_language_field.widget.decompress(cleaned_and_compressed)
            ## decompressed will be something like:
            ##        [u'Spanish', u'spoken', u'primary']
            new_language, created = Language.objects.get_or_create(               
                    language_name=decompressed[0],
                        )
            new_language.save()
            
            ## Now that we have an entry in the Language table, we need to make 
            ## an entry in the UserLanguage table to connect this Language
            ## entry to a particular Contact. This is also the appropriate spot
            ## to store information about whether this particular language is 
            ## the primary language, and whether it is written or spoken, etc.
            new_user_language_join, created = \
                UserLanguage.objects.get_or_create(
                    contact = Contact.objects.get(id=self.contact_id), 
                    language_name = new_language,
                    language_usage = decompressed[1],
                    language_preference = decompressed[2]
                    )
            new_user_language_join.save()   
                 
    def get_language_data(self, touched_add_form, touched_edit_form,
        fresh_add_form, fresh_edit_form):
        """
        Add one or more language fields. 
        """
        ## For 'touched' forms, we now don't need to do much more - the language
        ## etc fields will be in the request, and so the fields will have been
        ## correctly built onto the form by the superclass __init__ methods that
        ## was called earlier. We just need to build a self.language_field_list
        ## so that the template can display us properly and so on.
        ## This will store a list of the names of all the language fields on 
        ## this form, ie language_1, language_2, and so on.
        self.language_field_list = []
        
#        if touched_add_form or touched_edit_form:
#            for key in self.data:
#                if key[0:9] == 'language_':
#                    self.language_field_list.append(key)
#                    
        if touched_edit_form:
            for key in self.data:
                if key[0:9] == 'language_':
                    self.language_field_list.append(key)
                    ## Hopefully it doesn't matter what the initial value is,
                    ## since as soon as any one tryies to 'get' the item, it
                    ## will go through __getitem__ which will create a bound
                    ## field, which will get it's data out of self.data. 
                    self.fields[key] = forms.CharField(max_length=40, 
                    initial='Abbotsford', required=False)
                
        ## For 'fresh' forms, we still need to add 
        ## these fields, as they were not part of the base_fields in the class
        ## definition.
        ## 

        if fresh_add_form:
            ## If there is no contact_id, we are a fresh add form - we just
            ## offer them a default number of language fields, say 2 or 3.
            num_languages=2           
            for i in range(num_languages):
                field_name = 'language_%s' % (i+1)     
                self.fields[field_name] = forms.CharField(max_length=40, 
                    initial='Esperanto', required=False)
                self.language_field_list.append(field_name)
        if fresh_edit_form:
            ## If we have a contact_id already, then we are an edit form, and 
            ## we need to pull out any existing language data from the database.        
            user_language_joins = UserLanguage.objects.filter(
                contact__exact=self.contact_id)
            pdb.set_trace()
            for i, entry in enumerate(user_language_joins):
                language_name = Language.objects.get(id=entry.language_name_id).language_name
                field_name = 'language_%s' % (i+1)    
                self.fields[field_name] = forms.CharField(
                    max_length=40, 
                    initial=language_name, 
                    required=False)
                self.language_field_list.append(field_name) 
                ## Need to put the value into the form data as well, we can't
                ## expect the form to get the data out of the field...
                ## Why oh Why?!
                self.data[field_name]=language_name
                
               
            
 
             


#                            

================================================================================


<!--

<form method="post" class = "a_form" id = "test_form">    <!-- start form -->
    
<fieldset title="Name" style="padding: 20px; margin:10px;">
<legend style="font-weight: bold">Name</legend>
       
<span>{{ form.first_name.label_tag }} {{ form.first_name }}</span>
<span class="helptext">{{ form.first_name.help_text }}</span>
{% if form.first_name.errors %}
<ul class="errorlist">{{ form.first_name.errors }}</ul>
{% endif %}

<span>{{ form.last_name.label_tag }} {{ form.last_name }}</span>
<span class="helptext">{{ form.last_name.help_text }}</span>
{% if form.last_name.errors %}
<ul class="errorlist">{{ form.last_name.errors }}</ul>
{% endif %}

</fieldset>                                   <!-- end fieldset title="Name" -->
 
<fieldset title="Pets" style="padding: 20px;  margin:10px;">
<legend style="font-weight: bold">Pets</legend>
             
{% for pet in form.pets %}

<fieldset title="Pet #" style="padding: 20px;  margin:10px;">
<legend style="font-weight: bold">Pet #{{forloop.counter}}</legend>
<p>
<span>{{ pet.label_tag }} {{ pet }}</span>
<span class="helptext">{{ pet.help_text }}</span>
{% if pet.errors %}
<ul class="errorlist">{{ pet.errors }}</ul>
{% endif %}
</p>
</fieldset>

{% endfor %}     

<input type="submit" value = "Submit Owner"/>             <!-- submit button -->
</form>                                                        <!-- end form -->

-->
================================================================================
OwnerForm
----------

class body:
pets_template

__init__



================================================================================
    def not_build_pet_fields(self):
        """
        Add one or more pet-entry widgets.
        """
        ## stage_type tells us the type ('add' or 'edit') and freshness of 
        ## the form.
        stage_type=self.stage_type
        self.repeating_pet_list = []
        
        if (stage_type == 'touched_add') or (stage_type == 'touched_edit'):   
        ## If we've been 'touched', simply rebuild our self.fields and
        ## self.repeating_phone_list using information in self.data
        ## that was passed in via the request.           
            pets = self.get_pet_names()
            ## Build a 'multi' input for each of these:
            for pet in pets: 
                ## And instantiate a PhoneFields object with a PhoneFieldsWidget
                ## that has this initial value. Also create an entry in
                ## self.fields (needed so that form['item'] binds this Field)
                ##
                ## self.data is already corectly set-up with all the data we 
                ## need, and our widgets know how to get their values out of
                ## self.data, so we don't need to give them any value for 
                ## 'initial'.
                self.fields[pet] = PetFields(widget=PetWidget(), name=pet)
                ## Finally, stick the bound version of this field into
                ## a list for the templates and the save() methods to iterate 
                ## over.
                self.repeating_pet_list.append(self.__getitem__(pet))
                    
        if self.stage_type=='fresh_edit':
            ## If we are 'fresh', we need to get the relevant data out of the 
            ## database, then build the appropriate 'field' object for each 
            ## one.
            #pdb.set_trace()
            owner = Owner.objects.get(id=self.owner_id)
            pets = Pet.objects.filter(owner__exact=owner)
            for i, pet in enumerate(pets): 
                pet_id = pet.id       
                petname = Pet.objects.get(id=pet_id).name
                                
                fieldname = 'repeating_pet_%s' % i
                self.fields[fieldname] = PetFields( 
                    initial=None,
                    label="pet id #%s" % pet_id,
                    name=fieldname,
                    )
                ## Put correct values into form.data 
                #pdb.set_trace()
                pet_name_fieldname='%s_name'
               
                
                self.data[pet_name_fieldname % fieldname] = petname
                ## And finally append to the list used by the template and the 
                ## save method.
                self.repeating_pet_list.append(self.__getitem__(fieldname)) 
            
        if self.stage_type=='fresh_add':   
             ## If we are a fresh_add_form, we'd better hope that we have a 
             ## num_phones set - this is something to possibly fix up 
             ## later.
             self.make_fresh_pets(num_extra=2)
================================================================================
    def make_fresh_pets(self, num_extra=None):  

        if self.stage_type == 'touched_add' or self.stage_type == 'touched_edit':
            num_existing_pets = len(self.get_pet_names())   
            
        elif self.stage_type == 'fresh_add':
            num_existing_pets=0
            self.repeating_pet_list = []
        #pdb.set_trace()    
        for i in range(num_extra):
            name = 'repeating_pet_%s' % (num_existing_pets + i + 1)                      
            self.fields[name] = PetFields(
                widget=PetWidget(),
                initial='Jesse#Fred',
                label="pet id #%s" % "new",
                name=name,
                ) 

            self.repeating_pet_list.append(self.__getitem__(name))   
        #pdb.set_trace()        

================================================================================
    def get_pet_names(self):
        """
        Return a list of the fieldnames by which all of the
        existing pets are known by in self.fields by looking in
        self.data
        
        This will be something like 
        ['repeating_pet_1', 'repeating_pet_2'...'repeating_pet_N']
        
        """
        from sets import Set 
        pets=[]    
        for name in self.data.keys():
            split_name = name.split('_')
            if (split_name[0] == 'repeating' and split_name[1] == 'pet'):
                fieldname = '_'.join( [split_name[0], split_name[1], split_name[2] ])
                pets.append(fieldname)       
        pets= Set(pets)
        ## Now pets should be something like just:
        ## ['repeating_phone_1', 'repeating_phone_2'] 
        return pets         
================================================================================
        if self.stage_type == 'fresh_edit': 
            """Subclasses will implement """
            ## If we are 'fresh', we need to get the relevant data out of the 
            ## database, then build the appropriate 'field' object for each 
            ## one.
            #pdb.set_trace()
            owner = Owner.objects.get(id=self.owner_id)
            pets = Pet.objects.filter(owner__exact=owner)
            fields=[]
            #pdb.set_trace()
            for i, pet in enumerate(pets): 
                pet_id = pet.id       
                pet_name = pet.name
                #pet_delete=None
                """ Or if not using subclasses  to implement, try using
                form.initial as a whole rather than populating the individual 
                fields perhaps?"""
                fieldname = 'pet_%s' % (i+1)
                self.fields[fieldname] = PetField(
                    widget=PetWidget(),
                    initial="%s#%s#" % (pet_id, pet_name),
                    label="lovely pet #%s" % pet_id,
                    )
                
                ## A reference to go into the FieldList object that the form
                ## will reference.
                fields.append(self.fields[fieldname])       
                # Put correct values into form.initial
                #pdb.set_trace()
                pet_id_fieldname='%s_pet_id'
                pet_name_fieldname='%s_pet_name'
                phone_delete_fieldname='%s_phone_delete'
                
                self.initial[pet_id_fieldname % fieldname] = pet_id
                self.initial[pet_name_fieldname % fieldname] = pet_name
            ## Give the whole form a reference to our FieldList
            self.pets=FieldList(fields=fields, base_name='pet')
            self.pets.set_form(self)







================================================================================
class PhoneFieldsWidget(forms.MultiWidget):
    """
    A Widget that splits phone input into four seperate html widgets:
    
    -  <input type="text">  for the actual phonenumber.
    -  <input type="select">  for the phone-type(mobile, land-line, etc).
    -  <input type="select">  for the user's preference for being called on this
       number.
       <input type="checkbox">  to delete this item.
       
    Designed to be used with the PhoneFields() class.
       
    """
    contact_phone_join_id_fieldname = '%s_contact_phone_join_id'
    phone_number_fieldname = '%s_phone_number'
    phone_type_fieldname = '%s_phone_type'
    phone_preferred_fieldname = '%s_phone_preferred'
    phone_delete_fieldname = '%s_phone_delete'

    def __init__(self, attrs=None):
        """
        Initialise this multiwidget by passing in the four widgets 
        required, then calling the __init__ method of the superclass.
        The last two widgets are select-boxes so they need to have the correct 
        choices-list passed in as well.
        """
        widgets = (
                   forms.TextInput(attrs={'widget_name': 'contact_phone_join_id'}), 
                   forms.TextInput(attrs={'widget_name': 'phone_number'}), 
                   forms.Select(attrs={'widget_name': 'phone_type'}, choices=(PHONE_CHOICES)),
                   forms.Select(attrs={'widget_name': 'phone_preferred'}, choices=(PREFERENCE_CHOICES)),
                   #cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
                   PhoneDeleteCheckbox(
                       attrs={
                              'widget_name': 'phone_delete', 
                              'id_suffix': 'phone_delete_id'
                             },
                       ## We want the box unchecked when first rendered ;) 
                       check_test=False),
                       #check_test=lambda value: True==False),
                   )
        super(PhoneFieldsWidget, self).__init__(widgets, attrs)

    def render(self, name, value, attrs=None):
        # value is a list of values, each corresponding to a widget
        # in self.widgets.
        if not isinstance(value, list):
            value = self.decompress(value)
        output = []
        for i, widget in enumerate(self.widgets):
            try:
                widget_value = value[i]
                widget_name = widget.attrs.get('widget_name')
                widget_id_suffix = widget.attrs.get('id_suffix')          
                if widget_id_suffix:
                    attrs['id'] = name + '_' + widget_id_suffix
            except KeyError:
                widget_value = None
                widget_name = 'anonymous'
            output.append(widget.render(name + '_%s' % widget_name, widget_value, attrs))
        return self.format_output(output)
    
    def decompress(self, value):
        """ """
        if value:
            return value.split('#')
        return [None, 'Ook', 'Ook!', 'eeeeegleeeeee!!!!!', u'False']

    def value_from_datadict(self, data, name):
        contact_phone_join_id = data.get(self.contact_phone_join_id_fieldname % name)
        phone_number = data.get(self.phone_number_fieldname % name)
        phone_type = data.get(self.phone_type_fieldname % name)
        phone_preferred = data.get(self.phone_preferred_fieldname % name)
        phone_delete = data.get(self.phone_delete_fieldname % name)                    
        #if phone_number and phone_type and phone_preferred:
        if True:
            x= [contact_phone_join_id, 
                phone_number, phone_type, phone_preferred, 
                unicode(phone_delete)]
            print "value_from_datadict, name is %s, returning %s" % (name, x)
            return  x
        else: 
            raise Exception, "Problem getting PhoneFieldsWidget value out of data dictionary ..."
    

================================================================================
                                               <!--  fieldset title="Phones" -->
<fieldset title="Phones" style="padding: 20px;  margin:10px;"> 
<legend style="font-weight: bold">Phones</legend>
             
{% for phone in form.phones %}

<fieldset title="Phone #" style="padding: 20px;  margin:10px;">
<legend style="font-weight: bold">Phone #{{forloop.counter}}</legend>
<p>
<span>{{ phone.label_tag }} {{ phone }}</span>
<span class="helptext">{{ phone.help_text }}</span>
{% if phone.errors %}
<ul class="errorlist">{{ phone.errors }}</ul>
{% endif %}
</p>
</fieldset>

{% endfor %}     

<input type="submit" name="add_another_phone" value="Add another phone?"/> 

</fieldset>                                <!--  end fieldset title="Phones" -->================================================================================
================================================================================

/* background-image: url("http://content8.flixster.com/photo/55/85/44/5585442_gal.jpg");  */
================================================================================
def contact(request, main_object_id=None):
    """ """
    ## See contrib/admin/views.main.add_stage() for some ideas...   
    ## If user has hit the submit button, the request method will be 'POST'...
    ##pdb.set_trace() ***************
    if request.method == 'POST':
        ## The following works whether we are an adding form or an editing
        ## form.
        for key in request.POST.keys():
            ## The key should be 'add_another_pet', 'add_another_phone', etc
            if key.startswith('add_another'):
                base_name = key.split('_')[2]
                plural_name = base_name + 's'
                request_data = dict(request.POST)
                new_request_data = {}
                for key in request_data:
                    new_request_data[key] = request_data[key][0]   
                if main_object_id:
                    ## we are editing.      
                    object = Contact.objects.get(pk=main_object_id)                 
                    filled_form = ContactForm(initial=new_request_data, main_object=object)
                else:
                    ## we are adding.
                    filled_form = ContactForm(initial=new_request_data)
                    
                filled_form.__getattribute__(plural_name).add_fields(1)
                filled_form.put_fieldlists_into_form_fields()
                #pdb.set_trace()        
                ff=filled_form
                #pdb.set_trace()
                msg = "Here are the additional entry fields you asked for..."
                request.user.message_set.create(message=msg)
                return render_to_response(
                  'contact.html', 
                  {'form' : filled_form},
                  context_instance=RequestContext(request)
                  )          
        if main_object_id:
            ## We are an editing form    
            object = Contact.objects.get(pk=main_object_id)  
            filled_form =  ContactForm(request.POST, main_object=object)
        else:
             ## We are an adding form       
            filled_form = ContactForm(request.POST)
        ## handle_contact_form does validation and re-rendering or directing on. 
        ff=filled_form
        #pdb.set_trace()                  
        return handle_contact_form(request, filled_form)   
    ## If request.method is not 'POST', then the user has not yet hit the 
    ## submit button  -->  render an empty form for them to fill in ...       
    else:  
        if main_object_id:   
            #pdb.set_trace() 
            object = Contact.objects.get(pk=main_object_id)
            empty_form = ContactForm(main_object=object)
#            emf=empty_form 
#            pdb.set_trace() 
            form_instructions = "Edit an existing Contact here!"
        else:
            empty_form = ContactForm()
            form_instructions = "Add a new Contact here!"
    ef=empty_form
    #pdb.set_trace()      
    return render_to_response(
        'contact.html', 
        {
         'form' : empty_form,
         'form_instructions': form_instructions,
         },
        context_instance=RequestContext(request)
        )                                     
contact = login_required(contact) 

================================================================================
Steps to create an 'extensible' form.


1. Inherit from extensible form OR from another form that inherits from extenisble form.

2. Define most fields in the class body as usual (ie declaratively)

3. Any fields that are to be extendable (ie repeatable), define in the class
 body as FieldList objects, and give them a template field

4. In the template use 'for field in fieldlist:' (ie {% for pet in form.pets %}

5. In the views methods???

6. Over-ride the save method.

================================================================================
#include <cstdlib>
#include <iostream>
#include <assert.h>

void test_parameterised_stack_class();

const int STACK_SIZE = 100; //maximum size for stack

/*******************************************************************************
 * Stack class                                                                 *
 *                                                                             *    
 * Member functions                                                            *
 *      stack -- initialise the stack.                                         *
 *      push -- put an item on the stack.                                      *
 *      pop -- remove an item from the stack.                                  *
 ******************************************************************************/

// This class represents the template for the stack. Later, when we make 
// instances of this class, we will parameterise them with various 'kinds' of
// data. Thus an 'int' stack can be made to hold integers, a float stack to hold
// floats, and so on.
template<typename kind>
class stack {
    private:
        // Make count an unsigned int, to avoid generating a warning later when 
        // it is compared to sizeof(data)/sizeof(data[0]).
        unsigned int count;             //Current number of items in the stack.
        kind data[STACK_SIZE];   //The items themselves, held in an array.
    public:
        // Initialise the stack.
        stack() {
            count = 0;  // Zero the stack.
        }
        // Push an item onto the stack.
        void push(const kind item) {
            assert(count >= 0);
            assert(count < sizeof(data)/sizeof(data[0]));
            
            data[count] = item;
            ++count;
        }
        
        // Pop an item from the stack.
        kind pop() {
            // Stack goes down by one.
            --count;
            
            assert(count >= 0);
            assert(count < sizeof(data)/sizeof(data[0]));
            
            // Then we return the top value.
            return (data[count]);
        }
        
}; // End of stack class declaration.
    

/*******************************************************************************
 * Stack testing function.                                                     *                                                         *                                                                             *
 *                                                                             *    
 * Test the stack out with a few different types of items.                     *                             *                                                                             *
 ******************************************************************************/

void test_parameterised_stack_class() {

std::cout << "Testing parameterised stack class \n";    
std::cout << "********************************* \n \n"; 

// The <int> tells us that this particular instance will hold integers.
stack<int> int_stack;  
std::cout << "\n\n";
std::cout << "Trying Integers \n";
std::cout << "=============== \n\n";

int_stack.push(1);
int_stack.push(2);
int_stack.push(3);
std::cout << "First item popped: " << int_stack.pop() << "\n";
std::cout << "Second item popped: " << int_stack.pop() << "\n";
std::cout << "Third item popped: " << int_stack.pop() << "\n";

// The <float> tells us that this particular instance will hold floats.
stack<float> float_stack;  
std::cout << "\n\n";
std::cout << "Trying Floats \n";
std::cout << "============= \n\n";

float_stack.push(1.0);
float_stack.push(2.2);
float_stack.push(3.3);
std::cout << "First item popped: " << float_stack.pop() << "\n";
std::cout << "Second item popped: " << float_stack.pop() << "\n";
std::cout << "Third item popped: " << float_stack.pop() << "\n";
  
// The <char> tells us that this particular instance will hold characters.
stack<char> char_stack;  
std::cout << "\n\n";
std::cout << "Trying Characters \n";
std::cout << "================= \n\n";

char_stack.push('A');
char_stack.push('B');
char_stack.push('C');
std::cout << "First item popped: " << char_stack.pop() << "\n";
std::cout << "Second item popped: " << char_stack.pop() << "\n";
std::cout << "Third item popped: " << char_stack.pop() << "\n";

};  // end of function 'test_parameterised_stack_class'.

int main()
{
    
test_parameterised_stack_class();

};
================================================================================
## update these with any extra settings which are releveant only for a local 
## machine, and also over-ride any values which are set here but which need to
## be changed for a local set-up. See the notes in the 
## local_settings.py.template file for more about how this all works.
try:
    import local_settings as local_settings
    locals().update(local_settings.__dict__)
except ImportError:
    print "No local_settings file!"

================================================================================
================================================================================
